#include "mysql.h"
#include "sendMsg.h"
bool connectDB(MYSQL **mysql){
    *mysql = mysql_init(NULL);
    char *host = "localhost";
    char *user = "root";
    char *passwd = "185463";
    char *db = "project";
    mysql_options(*mysql, MYSQL_SET_CHARSET_NAME, "utf8");
    MYSQL *ret = mysql_real_connect(*mysql, host, 
                                    user, passwd, db, 0, NULL, 0);
    if(ret == NULL){
        printf("数据库连接失败！失败原因：%s\n", 
               mysql_error(*mysql));
        return false;
    }
    //printf("数据库连接成功！\n");

    int res = mysql_select_db(*mysql, "project");
    if (res) {
        printf("选择数据库失败！失败原因%s\n", 
               mysql_error(*mysql));
        return false;
    }

    //printf("数据库选择成功！\n");

    return true;
}
int ADDTABLEDATA(MYSQL *mysql, char *Tname, char *field, char *value){
    char sql[SQL_MAX] = {0};
    snprintf(sql, SQL_MAX, "INSERT INTO %s (%s) values (%s)", Tname, field, value);
    printf("插入sql语句：%s\n", sql);
    int ret = mysql_query(mysql, sql);
    if (ret) {
        printf("插入表数据失败！失败原因：%s\n", mysql_error(mysql));
        return -1;
    }
    printf("插入表数据成功！\n");
    return 0;
}
char * SEARCHTableData(MYSQL *mysql, char *Tname, char *column, char *where){
    char sql[SQL_MAX] = {0};
    snprintf(sql, SQL_MAX, "SELECT %s FROM %s WHERE (%s)", column, Tname, where);
    printf("查询sql语句：%s\n", sql);
    int ret = mysql_query(mysql, sql);
    if (ret) {
        printf("查询表数据失败！失败原因：%s\n", 
               mysql_error(mysql));
        return NULL;
    }
    printf("查询表数据成功！\n");
    MYSQL_RES *result = mysql_store_result(mysql);
    if(result == NULL){
        printf("error query: %s\n", mysql_error(mysql));
        return NULL;
    }
    int rows = mysql_num_rows(result);
    int cols = mysql_num_fields(result);
    //printf("rows:%d, cols:%d\n", rows, cols);

    MYSQL_ROW row;
    char *back = (char *)calloc(1,1024);
    while((row = mysql_fetch_row(result)) != NULL){
        for(int i = 0; i < cols; ++i){
            char temp[1024] = {0};
            sprintf(temp, "%s", row[i]);
            //printf("temp:%s\n", temp);
            strcat(back, temp);
            //printf("back:%s", back);
        }
        //printf("\n");
    }
    mysql_free_result(result);
    return back;
}
char * returnTableData(MYSQL *mysql, char *Tname, char *column, char *where){
    char sql[SQL_MAX] = {0};
    snprintf(sql, SQL_MAX, "SELECT %s FROM %s WHERE (%s)", column, Tname, where);
    printf("查询sql语句：%s\n", sql);
    int ret = mysql_query(mysql, sql);
    if (ret) {
        printf("查询表数据失败！失败原因：%s\n", 
               mysql_error(mysql));
        return NULL;
    }
    printf("查询表数据成功！\n");
    MYSQL_RES *result = mysql_store_result(mysql);
    if(result == NULL){
        printf("error query: %s\n", mysql_error(mysql));
        return NULL;
    }
    int rows = mysql_num_rows(result);
    int cols = mysql_num_fields(result);
    printf("rows:%d, cols:%d\n", rows, cols);

    MYSQL_ROW row;
    char *back = (char *)calloc(1,1024);
    while((row = mysql_fetch_row(result)) != NULL){
        for(int i = 0; i < cols; ++i){
            char temp[1024] = {0};
            sprintf(temp, "%-10s ", row[i]);
            //printf("temp:%s\n", temp);
            strcat(back, temp);
            //printf("back:%s", back);
        }
        char tab[2] = "\n";
        strcat(back, tab);
    }
    mysql_free_result(result);
    return back;
}
int delTabledata(MYSQL *mysql, char *Tname, char *where){
    char sql[SQL_MAX] = {0};
    snprintf(sql, SQL_MAX, "DELETE FROM  %s WHERE (%s)", Tname, where);
    printf("删除sql语句：%s\n", sql);
    int ret = mysql_query(mysql, sql);
    if (ret) {
        printf("删除表数据失败！失败原因：%s\n", 
               mysql_error(mysql));
        return -1;
    }
    printf("删除表数据成功！\n");
    return 0;

}
int altTabledata(MYSQL *mysql, char *Tname, char *newfield, char *where){
    char sql[SQL_MAX] = {0};
    snprintf(sql, SQL_MAX, "UPDATE %s SET %s WHERE (%s)", Tname, newfield, where);
    printf("修改sql语句：%s\n", sql);
    int ret = mysql_query(mysql, sql);
    if (ret) {
        printf("修改表数据失败！失败原因：%s\n", 
               mysql_error(mysql));
        return -1;
    }
    printf("修改表数据成功！\n");
    return 0;

}
char *GenerateSalt(char *salt) {
    char str[STR_LEN + 1] = {0};
    int i,flag;
    srand(time(NULL));
    for(i = 0; i < STR_LEN; i ++) {
        flag = rand()%3;
        switch(flag) {
        case 0: str[i] = rand()%26 + 'a'; break;
        case 1: str[i] = rand()%26 + 'A'; break;
        case 2: str[i] = rand()%10 + '0'; break;
        }
    }
    //printf("%s\n", str);//输出生成的随机数。
    sprintf(salt, "$6$%s$", str);
    return salt;
}

char* substrinG(char* ch,int pos,int length){
    //定义字符指针 指向传递进来的ch地址
    char* pch=ch;
    //通过calloc来分配一个length长度的字符数组，返回的是字符指针。
    char* subch=(char*)calloc(sizeof(char),length+1);
    int i;
    //只有在C99下for循环中才可以声明变量，这里写在外面，提高兼容性。
    pch=pch+pos;
    //是pch指针指向pos位置。  
    for(i=0;i<length;i++)
    {
        subch[i]=*(pch++);
        //循环遍历赋值数组。  
    }   
    subch[length]='\0';//加上字符串结束符。  
    return subch;       //返回分配的字符数组地址。  
} 

int findParentId(MYSQL *mysql, char *pwd){
    char *ptfilename = {0};
    int len = strlen(pwd);
    int j = 0;
    for(int i = 0; i < len; ++i){
        if(pwd[i] == '/'){
            j = i + 1;
        }
    }
    ptfilename = substrinG(pwd, j, len - j);
    char where[SQL_MAX] = {0};
    sprintf(where, "filename = '%s'", ptfilename);
    int parent_id = atoi(SEARCHTableData(mysql, "virtualfile", "id", where));
    return parent_id;
}

int judge(MYSQL *mysql, char **pwd, int user_id, int *iu, int *cnt){
    //printf("strlen(pwd):%ld\n", strlen(pwd[0]));
    //int iu = ifLegality(mysql, pwd);
    //printf("ifLegality:%d\n", iu);
    if(iu[0] == -1){
        //printf("?\n");
        return 0;
    }
    else if(iu[0] == -2){
        return -1;
    }
    //if(iu){
    //    judge(mysql, pwd);
    //}
    else if(iu[0] == 0 && cnt[0] == 0){
        ++cnt[0]; 
        iu[0] = ifLegality(mysql, pwd, user_id);
        //printf("递归里的pwd:%s\n", pwd[0]);
        judge(mysql, pwd, user_id, iu, cnt);
    }
    else if(iu[0]>=0 && cnt[0] != 0){
        int id = findParentId(mysql, pwd[0]);
        //printf("pwd:%s\n", pwd[0]);
        //printf("id:%d\n", id);
        //printf("iu:%d\n", iu[0]);
        if(id == iu[0]){
            ++cnt[0];
            iu[0] = ifLegality(mysql, pwd, user_id);
            //      printf("iu:%d\n", iu[0]);
            judge(mysql, pwd, user_id, iu, cnt);
        }else{
            //      printf("!!\n");
            return -100;
        }
    }
    return 0;
}
int ifLegality(MYSQL *mysql, char **pwd, int user_id){
    char *ptfilename = {0};
    //printf("pwd[0]:%s\n", pwd[0]);
    int len = strlen(pwd[0]);
    int j = 0;
    for(int i = 0; i < len; ++i){
        if(pwd[0][i] == '/'){
            j = i + 1;
        }
    }
    ptfilename = substrinG(pwd[0], j, len - j);
    //printf("ptfilename:%s\n", ptfilename);
    char where[SQL_MAX] = {0};
    sprintf(where, "filename = '%s' and owner_id = %d", ptfilename, user_id);
    int type = atoi(SEARCHTableData(mysql, "virtualfile", "type", where));
    if(type != 1){
        return -2;
    }
    pwd[0] = substrinG(pwd[0], 0, j - 1);
    if(pwd[0][0] == ' '){
        int parent_id = atoi(SEARCHTableData(mysql, "virtualfile", "id", where));
        //printf("over\n");
        return parent_id;
    }
    int parent_id = atoi(SEARCHTableData(mysql, "virtualfile", "parent_id", where));
    //printf("parent_id:%d\n", parent_id);
    //printf("pwd:%s\n", pwd[0]);
    return parent_id;
}
int mkDir(MYSQL *mysql, int peerfd, int user_id, char *newdir){
    char where[SQL_MAX] = {0};
    sprintf(where, "id = %d", user_id);
    char pwd[100] = {0};
    strcpy(pwd, SEARCHTableData(mysql, "user", "pwd", where));
    int owner_id = user_id;
    int parent_id = findParentId(mysql, pwd);
    char fields[1024] = {0};
    sprintf(fields, "parent_id, filename, owner_id, md5, type");
    //printf("fields:%s\n", fields);
    char values[1024] = {0};
    sprintf(values, "%d, '%s', '%d', 'dir', 1", parent_id, newdir, owner_id);
    //printf("values:%s\n", values);
    if(ADDTABLEDATA(mysql, "virtualfile", fields, values)==0){
        char *msg = "创建文件夹成功！\n";
        sendMsg(peerfd, msg);
        return 0;
    }
    char *msg = "创建文件夹失败!\n";
    sendMsg(peerfd, msg);
    return -1;
}
int cd(MYSQL *mysql, int peerfd, int user_id, char *path){
    //判断合法性
    char *pwd = (char *)calloc(1, 100);
    int *iu = (int *)calloc(1,4);
    int *cnt = (int *)calloc(1,4);
    strcpy(pwd, path);
    int judg = -1;
    judg = judge(mysql, &pwd, user_id, iu, cnt);
    //printf("judg:%d\n", judg);
    judg = judge(mysql, &pwd, user_id, iu, cnt);
    //printf("judg:%d\n", judg);
    if(judg != 0){
        //printf("路径不合法！\n");
        sendMsg(peerfd, "路径不合法！\n");
        return -1; 
    }   
    //更新user表pwd
    /*****相对路径转换为绝对路径*****/
    /*                              */    
    /********************************/
    char newpwd[SQL_MAX] = {0};
    sprintf(newpwd, "pwd = '%s'", path);
    //printf("newpwd:%s\n", newpwd);
    char where[SQL_MAX] = {0};
    sprintf(where, "id = %d", user_id);
    altTabledata(mysql, "user", newpwd, where);
    sendMsg(peerfd, path);
    return 0;
}
char* Pwd(MYSQL *mysql, int peerfd, int user_id, char *pwd){
    char where[SQL_MAX] = {0};
    sprintf(where, "id = %d", user_id);
    //char pwd[100] = {0};
    strcpy(pwd, SEARCHTableData(mysql, "user", "pwd", where));
    //sendMsg(peerfd, pwd);
    return pwd;
}                                          
int ls(MYSQL *mysql, int peerfd, int user_id, char *path){
    if(strlen(path) != 0){
        cd(mysql, peerfd, user_id, path);
    }   
    char pwd[100] = {0};
    //printf("before strcpy\n");
    strcpy(pwd, Pwd(mysql, peerfd, user_id, pwd));
    //printf("after strcpy\n");
    //printf("pwd:%s\n", pwd);
    int parent_id = findParentId(mysql, pwd);
    char where1[SQL_MAX] = {0};
    sprintf(where1, "parent_id = %d", parent_id);
    char rec[SQL_MAX] = {0};
    strcpy(rec, returnTableData(mysql, "virtualfile", "filename", where1));
    //printf("%s", rec);
    sendMsg(peerfd, rec);
    return 0;

}
int rm(MYSQL *mysql, int peerfd, int user_id, char *path){
    if(path[0] != '/'){
        char temp[1024] = {0};
        strcpy(temp, path);
        char pwd[100] = {0};
        strcpy(pwd, Pwd(mysql, peerfd, user_id, pwd));
        sprintf(path, "%s/%s", pwd, temp);
    }
    if(path[0] == '/'){
        //删除当前目录下的文件
        printf("jinlaile\n");
        char pwd[100] = {0};
        //strcpy(pwd, Pwd(mysql, 0, user_id, pwd));
        strcpy(pwd, path);
        int id = findParentId(mysql, pwd);
        //printf("path:%s, id:%d\n", path, id);
        char where[SQL_MAX] = {0};
        sprintf(where, "id = %d", id);
        if(atoi(SEARCHTableData(mysql, "virtualfile", "type", where)) == 1){
            char sql[SQL_MAX] = {0};
            snprintf(sql, SQL_MAX, "SELECT id FROM virtualfile WHERE parent_id = %d", id);
            //printf("查询sql语句：%s\n", sql);
            int ret = mysql_query(mysql, sql);
            if (ret) {
                printf("查询表数据失败！失败原因：%s\n",
                       mysql_error(mysql));
                return -1;
            }
            //printf("查询表数据成功！\n");
            MYSQL_RES *result = mysql_store_result(mysql);
            if(result == NULL){
                printf("error query: %s\n", mysql_error(mysql));
                return -1;
            }
            int rows = mysql_num_rows(result);
            int cols = mysql_num_fields(result);
            //printf("rows:%d, cols:%d\n", rows, cols);

            MYSQL_ROW row;
            while((row = mysql_fetch_row(result)) != NULL){
                for(int i = 0; i < cols; ++i){
                    char *child[1024] = {0};
                    child[i] = row[i];
                    printf("child:%s\n", child[i]);
                    char where1[SQL_MAX] = {0};
                    sprintf(where1, "id = %d", atoi(child[i]));
                    if(atoi(SEARCHTableData(mysql, "virtualfile", "type", where1)) == 1){
                        char newpath[1024] = {0};
                        //printf("newpath:%s\n", newpath);
                        sprintf(newpath, "%s/%s", path, SEARCHTableData(mysql, "virtualfile", "filename", where1));
                        //if(strlen(newpath) == 0){
                        //    delTabledata(mysql, "vrfile", where1);
                        //    printf("删除成功!\n");
                        //}
                        printf("newpath:%s\n", newpath);
                        sleep(1);
                        rm(mysql, peerfd, user_id, newpath);
                    }
                    char delwhere[1024] = {0};
                    sprintf(delwhere, "id = %d", atoi(child[i]));
                    delTabledata(mysql, "virtualfile", where1);
                    char *msg = "删除成功！\n";
                    //sendMsg(peerfd, msg);
                }
            }
        }
        if(atoi(SEARCHTableData(mysql, "virtualfile", "type", where)) == 0){
            delTabledata(mysql, "virtualfile", where);
           //printf("删除成功!\n");
            char *msg = "删除成功！\n";
            //sendMsg(peerfd, msg);
        }
            delTabledata(mysql, "virtualfile", where);
            //printf("删除成功!\n");
            char *msg = "删除成功！\n";
            //sendMsg(peerfd, msg);
    }
    return 0;
}
//int main(){
//    MYSQL *conn = NULL;
//    connectDB(&conn);
//    char username[26] = "user2";
//    char salt[20] = {0};
//    char pwd[100] = {0};
//    char *passwd = "666";
//    sprintf(pwd, "/%s/", username);
//    char cryptpasswd[200] = {0};
//    strcpy(cryptpasswd, crypt(passwd, GenerateSalt(salt)));
//    printf("%s\n", cryptpasswd);
//    char fields[4096] = {0};
//    sprintf(fields, "username, salt, cryptpasswd, pwd");
//    printf("%s\n", fields);
//    char values[4096] = {0};
//    sprintf(values, "'%s', '%s', '%s', '%s'", username,
//            salt, cryptpasswd, pwd);
//    printf("%s\n", values);
//    //ADDTABLEDATA(conn, "user", fields, values);
//    //SEARCHTableData(conn, "user", "*", "id = 10");
//    //delTabledata(conn, "user", "id = 10");
//    SEARCHTableData(conn, "user", "*", "id = 9");
//    altTabledata(conn, "user", "username = 'world'", "id = 9");
//    SEARCHTableData(conn, "user", "*", "id = 9");
//    // 关闭数据库
//    mysql_close(conn);
//}
